#ifndef _OK_H_
#define _OK_H_

// declaration of structures used in OK algorithm implementation

#include "Attribute.h"
#include "AttributeSet.h"
#include "Object.h"
#include "ObjectSet.h"
#include "OAPair.h"
#include "FormalContext.h"
#include "DataStructure.h"
#include "DataSetLoader.h"

#include <iostream>

// central data structure maintaining data loaded from external data source and
// reference pointers to speed up search operations
extern DataStructure data;

// closure computes a closure of OAPair element in local formal context
// represented by local_fc object
void Closure(const AttributeSet &prefix, OAPair &oa_pair, FormalContext &local_fc);
// sort_f is a sort function that compares two OAPair elements and returns true
// iff e1 is less or equal than e2, false conversely
void Order(FormalContext &local_fc, bool (*sort_f)(const OAPair &e1, const OAPair &e2) = NULL);
// determine local context for the first iteration of OK algorithm, i.e. 
// w/o considering the minimal support
FormalContext *OKLocalContext(const OAPair &oa, const FormalContext * const P);
// determine local context for the next iterations of OK algorithm (OK-Extend), i.e. 
// considering the minimal support
FormalContext *OKLocalContextMinSup(const OAPair &oa, const FormalContext * const P, unsigned int minSup);

void printFrequentClosedItemsets(const std::vector<const OAPair* const> *const fci, bool asChars=true, std::ostream &sink=std::cout);

void printOAPair(const OAPair * const oa, bool asChars=true, std::ostream &sink=std::cout);

void OK(DataStructure *ds, std::ofstream *fc, unsigned int minSup, bool (*sort_f)(const OAPair &e1, const OAPair &e2)=NULL, bool printAsChars=true);

bool isClosable(const OAPair & const oa_pair, FormalContext &local_fc);

void OKExtend(AttributeSet * prefix, FormalContext *P, bool (*sort_f)(const OAPair &e1, const OAPair &e2), unsigned int minSup, std::vector<const OAPair * const> *frequentClosedItemsets);
void printFormalContext(const FormalContext * const fc, std::ostream &sink=std::cout);

//cleans up the unwanted stuff related to formal contexts without messing with existing destructors
void cleanUpFormalContext(FormalContext* fc, bool removeObjects, bool removeAttributes);

//similar, yet for OAPair*
void cleanUpOAPair(OAPair* oa);

//and once more - for the closed itemsets collection
void cleanUpFrequentClosedItemsets(std::vector<const OAPair* const>* frequentClosedItemsets);

//a tool to perform safe insert (without overlaps)
void insertFrequentItemset(const OAPair* const oa, std::vector<const OAPair* const> * const fci);

bool checkOrder(const FormalContext * const fc);
#endif